﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HA.ModFlow.Domain.DomainLayer;




namespace HA.Data
{
    [Serializable]
    public class BCSeepageFace:BCType,ICloneable
    {

        public BCSeepageFace()
            : base()
        {


            //首先保证有一个应力期的值

            //this._multiConductance = new List<double>();

            //this._multiElevOffSet = new List<double>();

            //this._multiElevOffSetStart = new List<double>();

            //this._multiElevOffSetEnd = new List<double>();


            //for (int i = 0; i < this.NPeriods; i++)
            //{
            //    this._multiConductance.Add(0);
            //    this._multiElevOffSet.Add(0);
            //    this._multiElevOffSetEnd.Add(0);
            //    this._multiElevOffSetStart.Add(0);
            //}

 
        }




        BCDateDataCollection _multiConductance = new BCDateDataCollection();

        public BCDateDataCollection MultiConductance
        {
            get { return _multiConductance; }
            set { _multiConductance = value; }
        }


        //double _conductance;

        public double Conductance
        {
            get { return this._multiConductance.IsDataConst ? _multiConductance.ConstData : this._multiConductance.BCDatas[0].Value; }
            set
            {
                if (this._multiConductance.IsDataConst)
                    this._multiConductance.ConstData = value;
                else
                    this._multiConductance.BCDatas[0].Value = value;
            }
        }


        //double _elevOffSet;

       

        public double ElevOffSet
        {
            get { return this._multiElevOffSet.IsDataConst ? _multiElevOffSet.ConstData : this._multiElevOffSet.BCDatas[0].Value; }
            set
            {
                if (this._multiElevOffSet.IsDataConst)
                    this._multiElevOffSet.ConstData = value;
                else
                    this._multiElevOffSet.BCDatas[0].Value = value;
            }
        }


        BCDateDataCollection _multiElevOffSet = new BCDateDataCollection();

        public BCDateDataCollection MultiElevOffSet
        {
            get { return _multiElevOffSet; }
            set { _multiElevOffSet = value; }
        }



        //double _elevOffSetStart;

        public double ElevOffSetStart
        {
            get { return this._multiElevOffSetStart.IsDataConst ? _multiElevOffSetStart.ConstData : this._multiElevOffSetStart.BCDatas[0].Value; }
            set
            {
                if (this._multiElevOffSetStart.IsDataConst)
                    this._multiElevOffSetStart.ConstData = value;
                else
                    this._multiElevOffSetStart.BCDatas[0].Value = value;
            }
        }


        BCDateDataCollection _multiElevOffSetStart = new BCDateDataCollection();

        public BCDateDataCollection MultiElevOffSetStart
        {
            get { return _multiElevOffSetStart; }
            set { _multiElevOffSetStart = value; }
        }




        //double _elevOffSetEnd;

        public double ElevOffSetEnd
        {
            get { return this._multiElevOffSetEnd.IsDataConst ? _multiElevOffSetEnd.ConstData : this._multiElevOffSetEnd.BCDatas[0].Value; }
            set
            {
                if (this._multiElevOffSetEnd.IsDataConst)
                    this._multiElevOffSetEnd.ConstData = value;
                else
                    this._multiElevOffSetEnd.BCDatas[0].Value = value;
            }
        }



        BCDateDataCollection _multiElevOffSetEnd = new BCDateDataCollection();

        public BCDateDataCollection MultiElevOffSetEnd
        {
            get { return _multiElevOffSetEnd; }
            set { _multiElevOffSetEnd = value; }
        }


        //public override void OnNPeriodsChanged()
        //{
        //    base.OnNPeriodsChanged();

        //    //取得之前数据的个数
        //    int n = this.MultiConductance.Count;



        //    //开始更新数据


        //    if (n < this.NPeriods)
        //    {
        //        int nSub = this.NPeriods - n;

        //        for (int i = 0; i < nSub; i++)
        //        {
        //            this.MultiConductance.Add(0);
        //            this.MultiElevOffSet.Add(0);
        //            this.MultiElevOffSetEnd.Add(0);
        //            this.MultiElevOffSetStart.Add(0);
        //        }
        //    }

        //    else
        //    {
        //        int nSub = n - this.NPeriods;
        //        this.MultiConductance.RemoveRange(this.NPeriods, nSub);
        //        this.MultiElevOffSet.RemoveRange(this.NPeriods, nSub);
        //        this.MultiElevOffSetEnd.RemoveRange(this.NPeriods, nSub);
        //        this.MultiElevOffSetStart.RemoveRange(this.NPeriods, nSub);
        //    }


        //    //this.NPeriods;

        //}



        public object Clone()
        {
            //throw new NotImplementedException();

            BCSeepageFace bcsf = (BCSeepageFace)this.MemberwiseClone();

            bcsf._multiConductance = (BCDateDataCollection)this._multiConductance.Clone();

            bcsf._multiElevOffSet = (BCDateDataCollection)this._multiElevOffSet.Clone();

            bcsf._multiElevOffSetEnd = (BCDateDataCollection)this._multiElevOffSetEnd.Clone();

            bcsf._multiElevOffSetStart = (BCDateDataCollection)this._multiElevOffSetStart.Clone();

            return bcsf;
        }

        public override void MapToModflow(List<double> stressPeriods, List<ValueResult> ijkList, ModFlow.Domain.DomainLayer.ModFlowData mf, FeatureObject owner)
        {
            if (ijkList.Count <= 0) return;
            int k = ijkList[0].K;

            List<int> indice = new List<int>();

            List<Drain> Drains = new List<Drain>();


            double TotalValue = owner.GetTotalLValue();

            //double currentLength = 0;

            foreach (ValueResult item in ijkList)
            {
                //if (item.K != k)
                //{
                //    k = item.K;
                //    currentLength = 0;
                //}
                indice.Add(mf.GridData.GetIndex(item.I, item.J, item.K));

                Drain drain = new Drain(item.I, item.J, item.K, mf.GridData.RowsCount, mf.GridData.ColsCount, mf.GridData.LayersCount, mf.StressPeriods.InnerList.Count);


                //需要得到顶部海拔

                double[,] ele= mf.GridData.Elevations[item.K];

                double topElev=ele[item.I,item.K];


                if (owner is PointFO)
                {
                    this.assistMapToModFlow(stressPeriods, drain.Conductance, _multiConductance);
                    this.assistMapToModFlow(stressPeriods, drain.Elevation, _multiElevOffSet);

                    //drain.FirstConductance = this.Conductance;
                    //drain.FirstElevation = this.ElevOffSet + topElev;

                    for (int i = 0; i < stressPeriods.Count; i++)
                    {
                        drain.Elevation[i] += topElev;
                    }

                    //for (int i = 0; i < this.NPeriods; i++)
                    //{ 
                    //drain.Conductance[i]=this._multiConductance[i];
                    //drain.Elevation[i] = this._multiElevOffSet[i] + topElev;
                    //}

                }

                if (owner is LineFO)
                {
                    List<double> startEle = new List<double>(stressPeriods.Count);
                    List<double> endEle = new List<double>(stressPeriods.Count);

                    foreach (var sp in stressPeriods)
                    {
                        startEle.Add(0);
                        endEle.Add(0);
                    }

                    foreach (var sp in stressPeriods)
                    {
                        startEle.Add(0);
                        endEle.Add(0);
                    }

                    this.assistMapToModFlow(stressPeriods, drain.Conductance, _multiConductance);
                    this.assistMapToModFlow(stressPeriods, drain.Elevation, _multiElevOffSet);
                    this.assistMapToModFlow(stressPeriods, startEle, _multiElevOffSetStart);
                    this.assistMapToModFlow(stressPeriods, endEle, _multiElevOffSetEnd);

                    for (int i = 0; i < stressPeriods.Count; i++)
                    {
                        drain.Conductance[i] *= item.Value;
                        drain.Elevation[i] = startEle[i] + (endEle[i] - startEle[i]) * (item.LineCurrentTotalLength / TotalValue) + topElev;
                        
                    }

                    //for (int i = 0; i < this.NPeriods; i++)
                    //{
                    //    drain.Conductance[i] = this._multiConductance[i] * item.Value;
                    //    drain.Elevation[i] = this._multiElevOffSetStart[i] + (this._multiElevOffSetEnd[i] - this._multiElevOffSetStart[i]) * (item.LineCurrentTotalLength / TotalValue) + topElev;


                    //}
                    //currentLength += item.Value;
                }




                if (owner is PolygonFO)
                {
                    this.assistMapToModFlow(stressPeriods, drain.Conductance, _multiConductance);
                    this.assistMapToModFlow(stressPeriods, drain.Elevation, _multiElevOffSet);

                    for (int i = 0; i < stressPeriods.Count; i++)
                    {
                        drain.Conductance[i] *= item.Value;
                        drain.Elevation[i] += topElev;
                    }

                    //for (int i = 0; i < this.NPeriods; i++)
                    //{
                    //    drain.Conductance[i] = this._multiConductance[i] * item.Value;
                    //    drain.Elevation[i] = this._multiElevOffSet[i] + topElev;
                    //}
                }




                Drains.Add(drain);

            }

            //mf.SourceSinks.Drains.UpdateDrains(Drains, indice);  
            mf.SourceSinks.Drains.AddTempDrains(Drains);
        }
    }
}
